class RequestPool {
    constructor(maxConcurrency) {
        this.maxConcurrency = maxConcurrency;
        this.pendingRequests = 0;
        this.queue = [];
    }
    add(request) {
        return new Promise((resolve, reject) => {
            if (this.pendingRequests < this.maxConcurrency) {
                this.pendingRequests++;
                request()
                   .then(resolve)
                   .catch(reject);
            } else {
                this.queue.push({ request, resolve, reject });
            }
            this.processQueue();
        });
    }
    processQueue() {
        while (this.pendingRequests < this.maxConcurrency && this.queue.length > 0) {
            const { request, resolve, reject } = this.queue.shift();
            this.pendingRequests++;
            request()
               .then(resolve)
               .catch(reject)
               .finally(() => {
                    this.pendingRequests--;
                    this.processQueue();
                });
        }
    }
}

const requestPool = new RequestPool(2);
async function mockRequest() {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            const random = Math.random();
            if (random > 0.5) {
                resolve('Request completed');
            } else {
                reject('Request failed');
            }
        }, 500);
    });
}

(async () => {
    for (let i = 0; i < 10; i++) {
        await requestPool
           .add(mockRequest)
           .then(result => {
                console.log(result);
            })
           .catch(error => {
                console.log(error);
            });
    }
})();